package com.aaa.lib_java.mdm;

//import android.util.Base64;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.SignatureException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;

public class Encrypt {

    // PEM文件起止字符串
    public final static String PUBLIC_KEY_BEGIN = "-----BEGIN PUBLIC KEY-----";
    public final static String PUBLIC_KEY_END = "-----END PUBLIC KEY-----";
    public final static String PRIVATE_KEY_BEGIN = "-----BEGIN RSA PRIVATE KEY-----";
    public final static String PRIVATE_KEY_END = "-----END RSA PRIVATE KEY-----";
    // PEM文件行长度
    public final static int PEM_LINE_LENGTH = 64;
    // 换行
    public final static String PEM_NEW_LINE = "\r\n";// System.getProperty("line.separator");

    // 二进制转字符串
    public static String byte2hex(byte[] bytes) {
        StringBuffer retString = new StringBuffer();
        for (int i = 0; i < bytes.length; ++i) {
            retString.append(Integer.toHexString(0x0100 + (bytes[i] & 0x00FF))
                    .substring(1).toUpperCase());
        }
        return retString.toString();
    }

    // 字符串转二进制
    public static byte[] hex2byte(String hex) {
        byte[] bts = new byte[hex.length() / 2];
        for (int i = 0; i < bts.length; i++) {
            bts[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2),
                    16);
        }
        return bts;
    }

    /**
     * 生成RSA密钥对
     *
     * @param keySize 秘钥长度
     **/
    static public String[] generateKeyPair(int keySize) throws Exception {
        RSAPrivateKey privateKey;
        RSAPublicKey publicKey;
        KeyPairGenerator keyPairGen = null;

        try {
            keyPairGen = KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            throw e;
        }

        keyPairGen.initialize(keySize, new SecureRandom());
        KeyPair keyPair = keyPairGen.generateKeyPair();
        privateKey = (RSAPrivateKey) keyPair.getPrivate();
        publicKey = (RSAPublicKey) keyPair.getPublic();

        String[] ss = new String[2];
        ss[0] = byte2hex(privateKey.getEncoded());
        ss[1] = byte2hex(publicKey.getEncoded());
        return ss;
    }

    static public RSAPublicKey loadPublicKey(String publicKeyStr) throws Exception {
        return loadPublicKey(publicKeyStr, false);
    }

    // 获取公钥
    static public RSAPublicKey loadPublicKey(String publicKeyStr, boolean base64) throws Exception {
        RSAPublicKey publicKey = null;
        try {
            byte[] buffer;
            if (base64) {
//                buffer = Base64.decode(publicKeyStr, Base64.DEFAULT);
            } else {
            }
            buffer = hex2byte(publicKeyStr);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
            publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("无此算法");
        } catch (InvalidKeySpecException e) {
            throw new Exception("公钥非法");
        } catch (NullPointerException e) {
            throw new Exception("公钥数据为空");
        } catch (Exception e) {
            throw new Exception("公钥数据内容读取错误");
        }
        return publicKey;
    }

    // 获取私钥
    static public RSAPrivateKey loadPrivateKey(String privateKeyStr)
            throws Exception {
        RSAPrivateKey privateKey = null;
        try {
            byte[] buffer = hex2byte(privateKeyStr);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            privateKey = (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("无此算法");
        } catch (InvalidKeySpecException e) {
            throw new Exception("私钥非法");
        } catch (NullPointerException e) {
            throw new Exception("私钥数据为空");
        } catch (Exception e) {
            throw new Exception("私钥数据内容读取错误");
        }
        return privateKey;
    }

    /**
     * 私钥数字签名
     *
     * @param privateKey
     * @param degist
     * @return hex格式
     */
    static public String sign(RSAPrivateKey privateKey, byte[] degist)
            throws Exception {
        Signature sig;
        byte[] signature = null;
        try {
            sig = Signature.getInstance("SHA1WithRSA");
            sig.initSign(privateKey);// sig对象得到私钥

            // 签名对象得到原始数据
            sig.update(degist);// sig对象得到原始数据(现实中用的是原始数据的摘要，摘要的是单向的，即摘要算法后无法解密)
            signature = sig.sign();
            // System.out.println(sig.getProvider().getInfo());
        } catch (InvalidKeyException e) {
            throw new Exception(e);
        } catch (NoSuchAlgorithmException e) {
            throw new Exception(e);
        } catch (SignatureException e) {
            throw new Exception(e);
        }
        return byte2hex(signature);
    }

    /**
     * 公钥验证签名
     *
     * @param publicKey
     * @param plainText
     * @param sign      hex格式 OC传入
     */
    static public boolean verify(RSAPublicKey publicKey, byte[] plainText,
                                 String sign) throws Exception {
        Signature sig;
        try {
            sig = Signature.getInstance("SHA1WithRSA");
            // 使用公钥验证
            sig.initVerify(publicKey);// sig对象得到公钥

            // 签名对象得到原始信息
            sig.update(plainText);// sig对象得到原始数据(现实中是摘要)

            // sig对象用公钥解密签名signature得到原始数据(即摘要)，一致则true
            if (sig.verify(hex2byte(sign))) {
                // System.out.println("签名验证正确！！" + new String(plainText,
                // "UTF8"));
                return true;
            } else {
                // System.out.println("签名验证失败！！");
                return false;
            }
        } catch (InvalidKeyException e) {
            throw new Exception(e);
        } catch (NoSuchAlgorithmException e) {
            throw new Exception(e);
        } catch (SignatureException e) {
            throw new Exception(e);
        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    public static byte[] encrpy(RSAPrivateKey serverKey, byte[] data) throws Exception {
        if (serverKey == null) {
            throw new Exception("解密公钥为空, 请设置");
        } else {
            Cipher var2 = null;
            try {
                var2 = Cipher.getInstance("RSA");
                var2.init(Cipher.ENCRYPT_MODE, serverKey);
                byte[] rst = var2.doFinal(data);
                return rst;
            } catch (NoSuchAlgorithmException var4) {
                throw new Exception("无此解密算法");
            } catch (NoSuchPaddingException var5) {
                var5.printStackTrace();
                return null;
            } catch (InvalidKeyException var6) {
                throw new Exception("解密私钥非法,请检查");
            } catch (IllegalBlockSizeException var7) {
                throw new Exception("密文长度非法");
            } catch (BadPaddingException var8) {
                throw new Exception("密文数据已损坏");
            }
        }
    }

    public static byte[] decrypt(RSAPublicKey privateKey, byte[] cipherData)
            throws Exception {
        if (privateKey == null) {
            throw new Exception("解密私钥为空, 请设置");
        }
        Cipher cipher = null;
        try {
            String transformation = "RSA";
            transformation = "RSA/ECB/PKCS1Padding";
//            transformation = RSA_None_PKCS1Padding;
            cipher = Cipher.getInstance(transformation);
            System.out.println("Encrypt 公钥解密填充=" + transformation);
            // BouncyCastleProvider());
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] output = cipher.doFinal(cipherData);
            return output;
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("无此解密算法");
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
            return null;
        } catch (InvalidKeyException e) {
            throw new Exception("解密私钥非法,请检查");
        } catch (IllegalBlockSizeException e) {
            throw new Exception("密文长度非法");
        } catch (BadPaddingException e) {
            throw new Exception("密文数据已损坏");
        }
    }

    /**
     * 公钥加密过程 加密中，Android上Cipher的示例获取和JDK（webServer）上获取方式不一致。
     * Cipher.getInstance("RSA/None/PKCS1Padding"); 这是Android上获取Cipher的方法。
     *
     * @param publicKey     公钥
     * @param plainTextData 明文数据 !!!长度117 bytes以内，一般对摘要加密
     * @return
     * @throws Exception 加密过程中的异常信息
     */
    public static byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData)
            throws Exception {
        if (publicKey == null) {
            throw new Exception("加密公钥为空, 请设置");
        }
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("RSA");// , new
            // BouncyCastleProvider());
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] output = cipher.doFinal(plainTextData);
            return output;
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("无此加密算法");
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
            return null;
        } catch (InvalidKeyException e) {
            throw new Exception("加密公钥非法,请检查");
        } catch (IllegalBlockSizeException e) {
            throw new Exception("明文长度非法");
        } catch (BadPaddingException e) {
            throw new Exception("明文数据已损坏");
        }
    }

    /**
     * 私钥解密过程
     *
     * @param privateKey 私钥
     * @param cipherData 密文数据
     * @return 明文
     * @throws Exception 解密过程中的异常信息
     */
    public static byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData)
            throws Exception {
        if (privateKey == null) {
            throw new Exception("解密私钥为空, 请设置");
        }
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("RSA/None/PKCS1Padding");// , new
//            cipher = Cipher.getInstance("RSA");// , new
            // BouncyCastleProvider());
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] output = cipher.doFinal(cipherData);
            return output;
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("无此解密算法");
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
            return null;
        } catch (InvalidKeyException e) {
            throw new Exception("解密私钥非法,请检查");
        } catch (IllegalBlockSizeException e) {
            throw new Exception("密文长度非法");
        } catch (BadPaddingException e) {
            throw new Exception("密文数据已损坏");
        }
    }

    /**
     * 消息摘要 消息摘要是一种与消息认证码结合使用以确保消息完整性的技术 目前广泛使用的算法有MD4、MD5、SHA-1
     * 在java中进行消息摘要很简单， java.security.MessageDigest提供了一个简易的操作方法，如下 注意：消息摘要是单向的
     *
     * @param text
     * @return 字节数组 utf-8
     */
    public static byte[] degist(byte[] text) throws Exception {
        try {
            // 使用getInstance("算法")来获得消息摘要,这里使用SHA-1的160位算法或者MD5算法
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
            // MessageDigest messageDigest = MessageDigest.getInstance("MD5");

            // System.out.println("/n" + messageDigest.getProvider().getInfo());

            // 开始使用算法
            messageDigest.update(text);

            // 输出算法运算结果
            return messageDigest.digest();
        } catch (NoSuchAlgorithmException e) {
            throw new Exception(e);
        }
    }

    public static Key genDESKey(String strKey) {
        Key key = null;
        try {
            KeyGenerator _generator = KeyGenerator.getInstance("DES");
            _generator.init(new SecureRandom(strKey.getBytes()));
            key = _generator.generateKey();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return key;
    }

    public static byte[] encryptDES(byte[] bytes, Key key) throws Exception {
        Cipher cipher = Cipher.getInstance("DES");
        // Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        ByteArrayInputStream is = new ByteArrayInputStream(bytes);
        ByteArrayOutputStream out = new ByteArrayOutputStream(bytes.length);
        CipherInputStream cis = new CipherInputStream(is, cipher);
        byte[] buffer = new byte[4096];
        int r;
        while ((r = cis.read(buffer)) > 0) {
            out.write(buffer, 0, r);
        }
        cis.close();
        is.close();
        out.close();
        byte[] encryptData = out.toByteArray();
        return encryptData;
    }

    public static byte[] decryptDES(byte[] bytes, Key key) throws Exception {
        Cipher cipher = Cipher.getInstance("DES");
        // Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key);
        ByteArrayInputStream is = new ByteArrayInputStream(bytes);
        ByteArrayOutputStream out = new ByteArrayOutputStream(bytes.length);
        CipherOutputStream cos = new CipherOutputStream(out, cipher);
        byte[] buffer = new byte[4096];
        int r;
        while ((r = is.read(buffer)) >= 0) {
            cos.write(buffer, 0, r);
        }
        cos.close();
        out.close();
        is.close();
        byte[] decryptData = out.toByteArray();
        return decryptData;
    }

    public static String encrypt(String s, Key key) throws Exception {
        String d = "";
        d = byte2hex(encryptDES(s.getBytes(), key));
        return d;
    }

    public static String decrypt(String s, Key key) throws Exception {
        String d = "";
        d = new String(decryptDES(hex2byte(s), key));
        return d;
    }

    /**
     * 取私钥完整字符串
     *
     * @param privateKey
     * @return
     */
    public static String getPrivateKeyString4ObjC(PrivateKey privateKey) {
        StringBuffer sb = new StringBuffer();

//        String strKey = replaceNewLine(getBASE64Encoder(privateKey.getEncoded()));
        String strKey = "";

        sb.append(PRIVATE_KEY_BEGIN);
        sb.append("\r\n");
        int keyLength = strKey.length();
        int lines = keyLength / PEM_LINE_LENGTH;
        for (int i = 0; i < lines; i++) {
            sb.append(strKey.substring(i * PEM_LINE_LENGTH, i * PEM_LINE_LENGTH
                    + PEM_LINE_LENGTH));
            sb.append("\r\n");
        }
        sb.append(strKey.substring(lines * PEM_LINE_LENGTH, keyLength));
        sb.append("\r\n");
        sb.append(PRIVATE_KEY_END);
        sb.append("\r\n");

        String hex = null;
        // hex = byte2hex(sb.toString().getBytes());
        hex = sb.toString();

        return hex;
    }

    // 保存公钥SSCrypto可接受的pem文件格式
    public static void savePublicKeyPEM(RSAPublicKey pubKey,
                                        String strPEMKeyFile) {
//        String strKey = replaceNewLine(getBASE64Encoder(pubKey.getEncoded()));
        String strKey = "";
        try {
            FileWriter keyFile = new FileWriter(strPEMKeyFile);
            PrintWriter out = new PrintWriter(keyFile);

            // Write text to file
            out.println(PUBLIC_KEY_BEGIN);
            int keyLength = strKey.length();
            int lines = keyLength / 64;
            for (int i = 0; i < lines; i++) {
                out.println(strKey.substring(i * PEM_LINE_LENGTH, i
                        * PEM_LINE_LENGTH + PEM_LINE_LENGTH));
            }
            out.println(strKey.substring(lines * PEM_LINE_LENGTH, keyLength));
            out.println(PUBLIC_KEY_END);
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 取得BASE64编码
//    public static String getBASE64Encoder(byte[] data) {
//        return Base64.encodeToString(data, Base64.DEFAULT);
//    }

    // Base64解码 使用时请注意参数异常
//    public static String getBase64Encode(String input) {
//        return Base64.encodeToString(input.getBytes(), Base64.DEFAULT);
//    }

    // Base64解码 使用时请注意参数异常
//    public static String getBase64Decode(String input) {
//        return new String(Base64.decode(input.getBytes(), Base64.DEFAULT));
//    }

    public static void savePrivateKeyPEM(PrivateKey pk, String path) {
        savePrivateKeyPEM(pk.getEncoded(), path);
    }

    public static void savePrivateKeyPEM(byte[] privateKeyBytes,
                                         String strPEMKeyFile) {
        String strKey = "";
//        String strKey = replaceNewLine(getBASE64Encoder(privateKeyBytes));

        try {
            FileWriter keyFile = new FileWriter(strPEMKeyFile);
            PrintWriter out = new PrintWriter(keyFile);

            // Write text to file
            out.print(PRIVATE_KEY_BEGIN);
            out.print("\r\n");
            int keyLength = strKey.length();
            int lines = keyLength / PEM_LINE_LENGTH;
            for (int i = 0; i < lines; i++) {
                out.print(strKey.substring(i * PEM_LINE_LENGTH, i
                        * PEM_LINE_LENGTH + PEM_LINE_LENGTH));
                out.print("\r\n");
            }
            out.print(strKey.substring(lines * PEM_LINE_LENGTH, keyLength));
            out.print("\r\n");
            out.print(PRIVATE_KEY_END);
            out.print("\r\n");
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除文本中的换行符
     *
     * @param strText 文本
     * @return
     */
    public static String replaceNewLine(String strText) {
        strText = strText.replaceAll("\r\n", "\n");
        strText = strText.replaceAll("\n", "\r\n");
        String strResult = "";
        int intStart = 0;
        int intLoc = strText.indexOf("\n", intStart);
        while (intLoc != -1) {
            strResult += strText.substring(intStart, intLoc - 1);
            intStart = intLoc + 1;
            intLoc = strText.indexOf("\n", intStart);
        }
        strResult += strText.substring(intStart, strText.length());
        return strResult;
    }

    public static void main(String[] args) throws Exception {

        /*
         * String s =
         * "30820278020100300D06092A864886F70D0101010500048202623082025E0201000281810088C00A064D462A6884FF1377A55A390D8585B1050C46B028A3B9C389A95A979DA4DBE444CFBD7F287608869CB838B2E1C696B3BBF1394CAE89D07C0A3CE44228D25B556A66A895A3D8F945B7861206B5F43D5A60BE187479C3DBEE1BD06AF3386DA163AB3B8DE4A59D0051B5A1A0A7B1D3A4CE54CDC2D26DF4D54B3863EBB87F02030100010281802709D392CAFA8DDEBAA0EAD8CC1E7E8D0AA208CFED1A3CEDCD1799E7B1AE07FC5BF4DE2C7AB599185EE1BE33FD2F4A79C3AC7FF0D6434A4DC54FFC291C0AF98BAC8C1030D92D9C57BB0262A4A4E8052A99F7225D908CAFFD8771351F68E0919CC5CA1871EEEC0206A7C31C26EBACB337D0FFACEF111068E42F1B404A126D84E9024100CC49AE0BC8970D3247D5910CDA6620C07FC3B2F0FB4A27C20D11788FFB6FDD45EE0BF9528476987F1449ABAAA8F69D16D05EE87630712D24B564ECEDFDB35673024100AB5DC37D69D54E4C7E83D5D921A3AFF4C85EF097638A22D1092AEB1AB2E5679E30BA96F09BA4A8ED76CE28591AE7A899572888DAB6FEF1D5F7678284FB2E86C5024100C687CC36F367A89176B21C56CB6078EFDABA8B0A1A8C047B574BE548B7E80CB84B1123E98785E1C98E23D24AF60D44B8C92392F2593D83CBAAE53C44454BA5F50241009E7F079B8C725C8C058BDC138AB881BAEE4459543C1D7C5C48956883F62895B0CB3318FE0B86BD337CE9EA899787E1F9899295196D9DD98163E559E3B30A725D024100AF5FA25C8EDC6D06A2224C639B7F88B47C44E22E4D3C4C0F6832AA9A6127526DA4BCE28694D0CB4A15998493812B56484B9494E1CFACC7C752DCA385473EE3E6"
         * ; PrivateKey prvKey = loadPrivateKey(s);
         *
         * String Base64PrvKeyString =
         * getBASE64Encoder(prvKey.getEncoded()).replaceAll("\n", "\r\n");
         * System
         * .out.println("private Key Base64 length:"+Base64PrvKeyString.length
         * ()); System.out.println("private Key Base64 Info:");
         * System.out.println(Base64PrvKeyString);
         */
        /*
         * String newline = replaceNewLine2(Base64PrvKeyString);
         * System.out.println("New Line length:"+newline.length());
         * System.out.println("New Line Info:"); System.out.println(newline);
         */
        // savePrivateKeyPEM(prvKey,"1.txt");
        // getPrivateKeyString4ObjC(prvKey);
        String publicS = "30820122300D06092A864886F70D01010105000382010F003082010A0282010100BF41223B971E0B33DB3A3AD5DE1A9462E76EB05781988956D510327E242507F06CFFEF2E0598C0B69056AB311CE893438CF85C154BDBA39EC8958C82E8DB7AB895AFC148EC7B02DEEA959E7479598B1D8958F02403C3529C9655FF9776B0A541A317D7C0C83229F796F609F1D1B2088D5AAF30961FDDE124F6A77D58FBA397ACC0D0C1E16D841FA45E39B4110769CF2508BD169C88A1DB0F85AA23BE1276D706B9AA6E8694ADB62A00A8FC9894CC375A9AB3B09BE1F48F4E686F1B062F9C7717D3B8D1AE4BC2CED3F7E551F6D61C9082A9CCC1E1C139B5417A5094EDD79C167F45942F665D3F5BA9126073D0A6B98EE71A1DF6134CBF912C6AEA5F08DBD1A6390203010001";
        String privateS = "308204BF020100300D06092A864886F70D0101010500048204A9308204A50201000282010100BF41223B971E0B33DB3A3AD5DE1A9462E76EB05781988956D510327E242507F06CFFEF2E0598C0B69056AB311CE893438CF85C154BDBA39EC8958C82E8DB7AB895AFC148EC7B02DEEA959E7479598B1D8958F02403C3529C9655FF9776B0A541A317D7C0C83229F796F609F1D1B2088D5AAF30961FDDE124F6A77D58FBA397ACC0D0C1E16D841FA45E39B4110769CF2508BD169C88A1DB0F85AA23BE1276D706B9AA6E8694ADB62A00A8FC9894CC375A9AB3B09BE1F48F4E686F1B062F9C7717D3B8D1AE4BC2CED3F7E551F6D61C9082A9CCC1E1C139B5417A5094EDD79C167F45942F665D3F5BA9126073D0A6B98EE71A1DF6134CBF912C6AEA5F08DBD1A63902030100010282010100ABC1EAE4694A69F52024A341FE3D1095E211DDFC383EACD876701D687B3D666BDCF7DBED10C9A6084E8807260C383248B0093B6944BEF3AA5DA9308F40601B4E39DFA54DC05298B969230532C4E84DAF30F1D6780189205FD0035B8EC2E0D108A95778438186CB79B6F12EED24CD26310C07D932795BE21E380522E50ED8541519BFED40805284A0C82B12D2FB447309428256FF2DA42A4A918A4BC131A6747A570D721107B039A92CFC545AD27A4A2785A14A8A49CC2EA0C184310FBB95802753C114BC7C8A1FB34ECD8317FB82AF409C75BE01652BD09BA99822C61543574FD7E73342BD05E2DDC5CBF2A2E6B210842CA97327DD70FABE1FC0533A7EE554A102818100F328FC6AEE719A8DD76C573C56660E2F0106698A688679C95B1558273739453754C28F7A820689AC327049FADD8596A19B5F7D719681CE5736A8BA5938117F9A09F9B87FBB88636D0B0A8F9D2F2FECF8E1A611129847F016EC73D93797725C2CEF3AB6E19F06C681D9DA097B2E942E5D168B07278CCA26DA84AE542CA50EA84302818100C95A7DF41F93A9FE37B13BDA17E05F6F84336A7F78B8476CF2B612A1102AFF08A781FB3D3BAC487642B27B0C9E4DEA3D8A0F67E6CE0C19F44E4080CF91CF1E0F5C60DDD4429A442995C12CDFC3D4330F8649B8660F4FB2461A87764CD0F23DE8C46A78FF4BCE73F0EF57052F41B3C4DDAD7F3D353CF1EF51314C47917EF73DD302818100D419F6441805843921A5E15A424AF7284D0E98D52063DCABA505B34551C864F5E4BB6988050F4ADBA78B871C8A4A52A058F52C68FE4DEFFCE732BA89C47C8EFF80A0112D6A198810BFC6D08ADD744292BDD1ABA6BAAA5564C9902BF36FE95339E6DB22571FEE3B0D5D47F1693FB205D73128C86ED942242E0BFA3C764CEBC21D0281806826699E1BB33AABE74CC2A3B5D3F6296D9D56C9E6BC931D7491DF22F684F6F41808F0D6A48621D921F8C61329D32D85756330A03F161D5AB41B43459AAB226659A73536F4D86CC781D1B10F7170D29486269DBE14CF696C3F8EB00F5DC8DF63062DF8B63D14E5FDCB1F1CEC6BB4BBF0DA2C4591C31B75696EF180D76E701EC702818100F1991E52E0A338337FB1817B0DF3218EAD5D8AA6335B0E649D10EEBAF4181247412DF6EFB0489AAE213026974C728505946D0B578C1132D779C9C15B37D23285DEE8D930CE229FD6DA040EDE86BA182EB7E340928B6D7AB334FB157A4D474FC2AF577D611F2126C10442E0649BF70E7BC64F4205DB85A2310B20E84243310820";
        RSAPrivateKey prvKey = loadPrivateKey(privateS);
        RSAPublicKey pubKey = loadPublicKey(publicS);
        byte[] encryStr = encrypt(pubKey, "010287".getBytes());
        System.out.println("加密=" + Arrays.toString(encryStr));
        String hexStr = byte2hex(encryStr);
//        System.out.println("加密后的串：" + hexStr);

        String s = decrypt(prvKey, encryStr).toString();
//        System.out.println("解密后：" + s);

        String pwd = "B50CE0C2DCE730BB6505EA576F852E89931D42E9F45C7F653F702A2ADD5476F2CD0D192C83927378AEC84E1FD149EA19D0C221E7BB139E3E6D1B95E90F01F515825B0321C405667B144ECC67A8EB5A97148A43580C2AD58D9554BEE75AF910EAEDEB4D2135B5E79ED5AE1FBC8A4FD87F9DE20B60B4E4C0E3C88AF3C17EE98DB0FDEAA1CFD7DE5CEA11674452B3F37DE3047756ADA3534D8E8C032374C23C188E41BD839D289BD54D7E47C88D4D1AB9C0545F714CF4295FA3C565D2E80954C35F64B9643CF6A9BD2E3A599773538EEB8434A46C9258952D2F5C9C42E79C2016226DFADAAA234DB5707536C83D08D3AA5D09D3D7A8327B6D058A54D7F3B8F9A09B";
        byte[] bytes = hex2byte(pwd);
        s = new String(decrypt(prvKey, bytes));
        System.out.println("解密后：" + s);

    }
}

